﻿using PhotoGallery.Data.Entity;
using PhotoGallery.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Web;
using System.Xml.Linq;

namespace PhotoGallery.Data.Repository
{
    public enum CreateUserException
    {
        //     The user was successfully created.
        Success = 0,
        //     The user name was not found in the database.
        InvalidUserName = 1,
        //     The password is not formatted correctly.
        InvalidPassword = 2,
        //     The password question is not formatted correctly.
        InvalidQuestion = 3,
        //     The password answer is not formatted correctly.
        InvalidAnswer = 4,
        //     The e-mail address is not formatted correctly.
        InvalidEmail = 5,
        //     The user name already exists in the database for the application.
        DuplicateUserName = 6,
        //     The e-mail address already exists in the database for the application.
        DuplicateEmail = 7,
    }

    public class UserRepository : BaseRepository
    {
        const string xmlData = "\\App_Data\\AuthData.xml",
            AuthDataXml = "AuthData.xml",
            OAuthDataXml = "OAuthData.xml",
            AlbumsMetaDataXml = "AlbumsMetaData.xml";

        string fileName;
        XDocument doc;
        List<User> users = new List<User>();


        public UserRepository()
        {
            fileName = BasePath + xmlData;

            LoadData(BasePath);
        }



        public List<User> Get()
        {
            return users;
        }

        public User Get(int id)
        {
            return users.FirstOrDefault(u => u.ID == id);
        }

        public User Get(string username, string password)
        {
            return users.FirstOrDefault(u => (u.Username == username || u.Email == username ) && u.Password == password ); 
        }

        public User GetByUsername(string username)
        {
            return users.FirstOrDefault(u => u.Username == username);
        }

        public User GetByEmail(string email)
        {
            return users.FirstOrDefault(u => u.Email == email);
        }

        public bool Create(User user)
        {
            try
            {
                user.ID = GetMaxValue() + 1;
                //user.CreateDate = DateTime.UtcNow;
                users.Add(user);

                XElement xml = new XElement("users",
                from i in users
                orderby user.ID
                select new XElement("user",
                          new XElement("id", i.ID),
                          new XElement("username", i.Username),
                          new XElement("email", i.Email),
                          new XElement("password", i.Password),
                          new XElement("active", true)
                          )
                );

                CreateGallery(user.Username);
                
                XDocument doc = new XDocument(xml);
                doc.Save(fileName);
            }
            catch (Exception ex)
            {
                throw new Exception("", ex.InnerException);
            }

            return true;
        }

        public void Edit(User user)
        {
            XElement node = doc.Root.Elements("user").Where(i => (int)i.Element("id") == user.ID).FirstOrDefault();

            node.SetElementValue("id", user.ID);
            node.SetElementValue("username", user.Username);
            node.SetElementValue("email", user.Password);
            node.SetElementValue("password", user.Password);

            doc.Save(fileName);
        }

        public void Delete(User user)
        {
            XElement node = doc.Root.Elements("user").Where(i => (int)i.Element("id") == user.ID).FirstOrDefault();

            node.SetElementValue("active", false);

            doc.Save(fileName);
        }

        public void Erise(int id)
        {
            User user = users.FirstOrDefault(a => a.ID == id);
            users.Remove(user);
            doc.Root.Elements("user").Where(i => (int)i.Element("id") == id).Remove();
            doc.Save(fileName);           
        }

        #region privateMethods

        private int GetMaxValue()
        {
            int count = doc.Descendants("user").Count();
            if (count > 0)
            {
                var maxID = (from prod in doc.Descendants("user")
                             select
                             (
                                         int.Parse(prod.Element("id").Value)
                             )).Max();

                return maxID;
            }
            else
            {
                return 0;
            }
        }

        private void LoadData(string filesDir)
        {
            if (!Directory.Exists(BasePath+AppDataFolder))
            {
                Directory.CreateDirectory(BasePath + AppDataFolder);
            }
            if (!File.Exists(fileName))
            {
                //string source = filesDir + AppDataFolder + "System\\" + AuthDataXml;
                doc =  new XDocument(
                          new XElement("users")
                        );
                doc.Save(fileName);
                //System.IO.File.Copy(source, dest, true);

                //source = filesDir + AppDataFolder + "System\\" + OAuthDataXml;
                string OAuthData = filesDir + AppDataFolder + "\\" + OAuthDataXml;
                doc = new XDocument(
                          new XElement("logins")
                        );
                doc.Save(OAuthData);
                //System.IO.File.Copy(source, dest, true);
            }
            else
            {
                doc = XDocument.Load(fileName);
            }
            
            var qry = from album in doc.Descendants("user")
                      select new User(
                                      Convert.ToInt32(album.Element("id").Value),
                                      album.Element("username").Value,
                                      album.Element("email").Value,
                                      album.Element("password").Value,
                                      album.Element("active").Value == "false" ? false : true
                                      );
            users.AddRange(qry.ToList<User>());
        }

        private void CreateGallery(string username)
        {
            //var filesDir = HttpContext.Current.Server.MapPath("~");
                        
            string path = BasePath + Settings.UploadsFolder;
            System.IO.Directory.CreateDirectory(path + username);
            DirectorySecurity ds = Directory.GetAccessControl(path + username);
            ds.AddAccessRule(new FileSystemAccessRule("Everyone",
                FileSystemRights.Read | FileSystemRights.Write, AccessControlType.Allow));
            Directory.SetAccessControl(path + username, ds);

            string albumsMetaData = path + username + "\\" + AlbumsMetaDataXml;
            XDocument doc =
              new XDocument(
                new XElement("albums")
                );
            doc.Save(albumsMetaData);
        }
        #endregion
    }
}